package com.ff.miaosha.netty;


import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.buffer.ByteBuf;


public abstract class CustomHeartbeatHander extends SimpleChannelInboundHandler<ByteBuf>{

    public static final byte PING_MSG = 1;
    public static final byte PONG_MSG = 2;
    public static final byte CUSTOM_MSG = 3;

    protected String name;
    private int heartbeatCount=0;

    public CustomHeartbeatHander(String name) {
        this.name = name;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
        if (byteBuf.getByte(4)==PING_MSG){
            sendPongMsg(channelHandlerContext);
        }else if (byteBuf.getByte(4)==PONG_MSG){
            System.out.println(name + " get pong msg from " + channelHandlerContext.channel().remoteAddress());
        }else{
            handleData(channelHandlerContext,byteBuf);
        }
    }

    private void sendPongMsg(ChannelHandlerContext channelHandlerContext) {
        ByteBuf buf=channelHandlerContext.alloc().buffer(5);
        buf.writeInt(5);
        buf.writeByte(PONG_MSG);
        channelHandlerContext.writeAndFlush(buf);
        heartbeatCount++;
        System.out.println(name + " sent pong msg to " + channelHandlerContext.channel().remoteAddress() + ", count: " + heartbeatCount);
    }

    protected void sendPingMsg(ChannelHandlerContext channelHandlerContext) {
        ByteBuf buf=channelHandlerContext.alloc().buffer(5);
        buf.writeInt(5);
        buf.writeByte(PING_MSG);
        channelHandlerContext.writeAndFlush(buf);
        heartbeatCount++;
        System.out.println(name + " sent ping msg to " + channelHandlerContext.channel().remoteAddress() + ", count: " + heartbeatCount);
    }

    protected abstract void handleData(ChannelHandlerContext channelHandlerContext,ByteBuf byteBuffer);

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
//        super.userEventTriggered(ctx, evt);
        if (evt instanceof IdleStateEvent){
            IdleStateEvent e= (IdleStateEvent) evt;
            switch (e.state()){
                case WRITER_IDLE:
                    handleWriterIdle(ctx);
                    break;
                case READER_IDLE:
                    handleReaderIdle(ctx);
                    break;
                case ALL_IDLE:
                    handleAllIdle(ctx);
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.err.println("---" + ctx.channel().remoteAddress() + " is active---");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.err.println("---" + ctx.channel().remoteAddress() + " is inactive---");
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
//        super.channelRegistered(ctx);
        System.err.println("---" + ctx.channel().remoteAddress() + " channelRegistered---");
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
//        super.channelUnregistered(ctx);
        System.err.println("---" + ctx.channel().remoteAddress() + " channelRegistered---");
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
//        super.channelReadComplete(ctx);
        System.err.println("---" + ctx.channel().remoteAddress() + " channelReadComplete---");
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
//        super.channelWritabilityChanged(ctx);
        System.err.println("---" + ctx.channel().remoteAddress() + " channelRegistered---");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//        super.exceptionCaught(ctx, cause);
        System.err.println("---" + ctx.channel().remoteAddress() + " handlerAdded---");
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
//        super.handlerAdded(ctx);
        System.err.println("---" + ctx.channel().remoteAddress() + " handlerAdded---");
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
//        super.handlerRemoved(ctx);
        System.err.println("---" + ctx.channel().remoteAddress() + " handlerAdded---");
    }

    protected void handleReaderIdle(ChannelHandlerContext ctx) {
        System.err.println("---READER_IDLE---");
    }

    protected void handleWriterIdle(ChannelHandlerContext ctx) {
        System.err.println("---WRITER_IDLE---");
    }

    protected void handleAllIdle(ChannelHandlerContext ctx) {
        System.err.println("---ALL_IDLE---");
    }

}
